home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / pt20pc.zip / INSDEL.C < prev    next >
C/C++ Source or Header  |  1991-02-04  |  14KB  |  469 lines

  1. #include "pt.h"
  2.  
  3. void pascal
  4. /* XTAG:insertChar */
  5. insertChar(ch)
  6.     unsigned char ch;
  7. {
  8.     extern struct window *selWindow;
  9.     extern long selBegin, selEnd;
  10.     extern unsigned char msgBuffer[];
  11.     extern struct openFile *files;
  12.     extern struct changeItem *change;
  13.     extern int nextChange;
  14.     extern long addPosition;
  15.     extern unsigned char *userMessages[];
  16.  
  17.     register struct changeItem *thisChange;
  18.     register struct openFile *ff;
  19.     struct piece *pp, *pp2, *thispp, *nextpp, *thirdpp;
  20.     long nn, offset;
  21.  
  22.     /* find out what piece 'selBegin' is in */
  23.     ff = &files[selWindow->fileId];
  24.     pp = findPiece(selBegin, ff, &nn);
  25.  
  26.     /* check if this is a readOnly file */
  27.     if( ff->readOnly ) {
  28.         sprintf(msgBuffer, userMessages[READONLYFILE], ff->origName);
  29.         msg(msgBuffer, 1);
  30.         return;
  31.     }
  32.  
  33.     offset = selBegin - nn;
  34.     if( offset > 0 ) {    /* we must split the piece */
  35.         /* we insert two new pieces */
  36.         /* nextpp is for the character we are inserting */
  37.         /* thirdpp is the split of portion of pp */
  38.         
  39.         /* update the fields of the new piece */
  40.         nextpp = getFreePiece();
  41.         nextpp->file = ADDFILE;
  42.         nextpp->position = addPosition;
  43.         nextpp->length = 1;
  44.  
  45.         /* update the fields of the split off piece */
  46.         thirdpp = getFreePiece();
  47.         thirdpp->file = pp->file;
  48.         thirdpp->position = pp->position + offset;
  49.         thirdpp->length = pp->length - offset;
  50.  
  51.         /* update the fields of the original piece */
  52.         /* pp->file remains the same */
  53.         /* pp->position remains the same */
  54.         pp->length = offset;
  55.         
  56.         /* link everything together again */
  57.         nextpp->nextPiece = thirdpp;
  58.         thirdpp->prevPiece = nextpp;
  59.         pp2 = pp->nextPiece;
  60.         thirdpp->nextPiece = pp2;
  61.         if( pp2 != NULL )
  62.             pp2->prevPiece = thirdpp;
  63.         nextpp->prevPiece = pp;
  64.         pp->nextPiece = nextpp;
  65.  
  66.         /* make the third piece the cached one */
  67.         ff->logPiece = thirdpp;
  68.         ff->loLogPiece = selBegin + 1;
  69.         ff->hiLogPiece = selBegin + thirdpp->length;
  70.     } else {    /* put in front of this piece */
  71.         /* can we put it at the end of the previous piece? */
  72.         thispp = pp->prevPiece;
  73.         /* if (1) there IS a previous piece and */
  74.         /*    (2) it is a piece in the add file and */
  75.         /*    (3) it is just before the piece we are adding */
  76.         /* then we coalsce the two pieces */
  77.         if( (thispp != NULL)    /* pp is not the first piece */
  78.          && (thispp->file == ADDFILE)    /* in the add file */
  79.          && (thispp->position+thispp->length == addPosition)
  80.         ) {
  81.             ++(thispp->length);    /* simply adjust the length */
  82.             ff->logPiece = pp;
  83.             ff->loLogPiece = nn + 1;
  84.             ff->hiLogPiece = nn + pp->length;
  85.         } else {
  86.             /* create a new piece for this character */
  87.             thispp = getFreePiece();
  88.             thispp->file = ADDFILE;
  89.             thispp->position = addPosition;
  90.             thispp->length = 1;
  91.             thispp->nextPiece = pp;
  92.             pp2 = pp->prevPiece;
  93.             pp->prevPiece = thispp;
  94.             thispp->prevPiece = pp2;
  95.             if( pp2 != NULL )
  96.                 pp2->nextPiece = thispp;
  97.             else
  98.                 ff->pieceList = thispp;
  99.             ff->logPiece = thispp;
  100.             ff->loLogPiece = selBegin;
  101.             ff->hiLogPiece = selBegin;
  102.         }
  103.     }
  104.  
  105.     /* record in the change history */
  106.     /* see if we can add this to the last insert */
  107.     thisChange = &change[nextChange];
  108.     if( thisChange->type == CINSERT
  109.      && thisChange->fileId == selWindow->fileId
  110.      && selBegin == thisChange->position+thisChange->length ) {
  111.         ++(thisChange->length);
  112.         ++(thisChange->firstPiece->length);
  113.     } else {
  114.         /* record in the change history */
  115.         IncrementNextChange();
  116.         thisChange = &change[nextChange];
  117.         thisChange->type = CINSERT;
  118.         thisChange->position = selBegin;
  119.         thisChange->length = 1;
  120.         thisChange->fileId = selWindow->fileId;
  121.         pp = getFreePiece();
  122.         thisChange->firstPiece = pp;
  123.         pp->file = ADDFILE;
  124.         pp->position = addPosition;
  125.         pp->length = 1;
  126.     }
  127.  
  128.  
  129.     /* add one character to the file */
  130.     ff->fileSize += 1;
  131.     writeChar(ch, addPosition++);
  132.  
  133.     /* invalidate the buffer cache */
  134.     ff->hiLogBuffer = -1L;
  135.  
  136.     /* record the fact that the file has changed */
  137.     ff->isChanged = 1;
  138.  
  139.     /* adjust window data even though we do not redraw */
  140.     updateTops(selWindow->fileId, selBegin, 1L);
  141.  
  142.     /* invalidate the last-row-found cache */
  143.     if( selWindow->posCurLast > selBegin )
  144.         selWindow->lastPosTop = -1;
  145.     
  146.     /* move the selection to char past new char */
  147.     selEnd = ++selBegin;
  148.     if( readChar(selWindow->fileId, selBegin) == '\r' ) {
  149.         if( readChar(selWindow->fileId, selBegin+1) == '\n' )
  150.             ++selEnd;
  151.     }
  152. }
  153.  
  154. int pascal
  155. /* XTAG:delChar */
  156. delChar()
  157. {
  158.     extern struct window *selWindow;
  159.     extern long selBegin, selEnd;
  160.     extern unsigned char msgBuffer[];
  161.     extern struct openFile *files;
  162.     extern struct changeItem *change;
  163.     extern int nextChange;
  164.     extern long addPosition;
  165.     extern unsigned char *userMessages[];
  166.  
  167.     long nn, offset;
  168.     register struct openFile *ff;
  169.     struct piece *pp, *thispp;
  170.     register struct changeItem *thisChange;
  171.  
  172.     /* find out what piece 'selBegin' is in */
  173.     ff = &files[selWindow->fileId];
  174.     pp = findPiece(selBegin, ff, &nn);
  175.  
  176.     /* check if this is a readOnly file */
  177.     if( ff->readOnly ) {
  178.         sprintf(msgBuffer, userMessages[READONLYFILE], ff->origName);
  179.         msg(msgBuffer, 1);
  180.         return 0;
  181.     }
  182.  
  183.     offset = selBegin - nn;
  184.     if( offset > 0 )
  185.         return 0;
  186.  
  187.     /* is the char to delete at the end of the previous piece? */
  188.     thispp = pp->prevPiece;
  189.     /* if (1) there IS a previous piece and */
  190.     /*    (2) it is a piece in the add file and */
  191.     /*    (3) it is just before the piece we are adding and */
  192.     /*    (4) we are not deleting the last char in the piece */
  193.     /*    (5) the preceding change was an insert */
  194.     /* then we coalsce the two pieces */
  195.     if( (thispp != NULL)    /* pp is not the first piece */
  196.      && (thispp->file == ADDFILE)    /* in the add file */
  197.      && (thispp->position+thispp->length == addPosition)
  198.      && (thispp->length >= 1)
  199.      && (change[nextChange].type == CINSERT)
  200.     ) {
  201.         --(thispp->length);    /* simply adjust the length */
  202.         ff->logPiece = pp;
  203.         ff->loLogPiece = nn - 1;
  204.         ff->hiLogPiece = nn + pp->length - 1;
  205.     } else
  206.         return 0;
  207.  
  208.     /* record in the change history */
  209.     /* see if we can add this to the last insert */
  210.     thisChange = &change[nextChange];
  211.     if( thisChange->type == CINSERT
  212.      && thisChange->fileId == selWindow->fileId
  213.      && selBegin == thisChange->position+thisChange->length ) {
  214.         --(thisChange->length);
  215.         --(thisChange->firstPiece->length);
  216.     } else {
  217.         ++(thispp->length);    /* re-adjust the length */
  218.         return 0;
  219.     }
  220.  
  221.     /* subtract one character to the file */
  222.     ff->fileSize -= 1;
  223.     --addPosition;
  224.  
  225.     /* invalidate the buffer cache */
  226.     ff->hiLogBuffer = -1L;
  227.  
  228.     /* record the fact that the file has changed */
  229.     ff->isChanged = 1;
  230.  
  231.     /* adjust window data even though we do not redraw */
  232.     updateTops(selWindow->fileId, selBegin, 1L);
  233.  
  234.     /* invalidate the last-row-found cache */
  235.     if( selWindow->posCurLast > selBegin )
  236.         selWindow->lastPosTop = -1;
  237.     
  238.     /* move the selection to char past new char */
  239.     selEnd = --selBegin;
  240.     if( readChar(selWindow->fileId, selBegin) == '\r' ) {
  241.         if( readChar(selWindow->fileId, selBegin+1) == '\n' )
  242.             ++selEnd;
  243.     }
  244.     return 1;
  245. }
  246.  
  247. int pascal
  248. /* XTAG:deleteChars */
  249. deleteChars(fileId, update, toScrap)
  250.     /* toScrap=0 --> do not put in the scrap */
  251.     /* toScrap=1 --> do put in the scrap */
  252.     /* toScrap=2 --> do not put in the scrap or the history */
  253.     int fileId, update, toScrap;
  254. {
  255.     extern unsigned char msgBuffer[];
  256.     extern int debug;
  257.     extern long selBegin, selEnd;
  258.     extern struct window *selWindow;
  259.     extern struct changeItem *change;
  260.     extern struct changeItem scrapBuffer;
  261.     extern int nextChange;
  262.     extern int selMode;
  263.     extern int scrapMode;
  264.     extern long addPosition;
  265.     extern struct openFile *files;
  266.     extern unsigned char *userMessages[];
  267.  
  268.     register struct openFile *ff;
  269.     long sb, nn, curPos, nextPos, offset, delLength;
  270.     int wasLF;
  271.     register struct piece *pp;
  272.     struct piece *pp2, *firstPP, *nextPP, *lastPP;
  273.     struct changeItem *thisChange;
  274.  
  275.     ff = &files[fileId];
  276.     nn = ff->fileSize;
  277.  
  278.     /* check if this is a readOnly file */
  279.     if( ff->readOnly ) {
  280.         sprintf(msgBuffer, userMessages[READONLYFILE], ff->origName);
  281.         msg(msgBuffer, 1);
  282.         return 0;
  283.     }
  284.  
  285.     /* eliminate the EOF marker from the selection